package com.example.service.impl;

import com.example.constant.MessageConstant;
import com.example.constant.PasswordConstant;
import com.example.constant.StatusConstant;
import com.example.dto.UserByStorePageQueryDTO;
import com.example.dto.UserDTO;
import com.example.dto.UserLoginDTO;
import com.example.dto.UserPageQueryDTO;
import com.example.entity.User;
import com.example.exception.AccountLockedException;
import com.example.exception.AccountNotFoundException;
import com.example.exception.PasswordErrorException;
import com.example.mapper.UserDao;
import com.example.result.PageResult;
import com.example.result.Result;
import com.example.service.UserService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * (User)表服务实现类
 *
 * @author makejava
 * @since 2024-03-12 16:46:49
 */
@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public User queryById(Long id) {
        return this.userDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param user 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<User> queryByPage(User user, PageRequest pageRequest) {
        long total = this.userDao.count(user);
        return new PageImpl<>(this.userDao.queryAllByLimit(user, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    @Override
    public User insert(User user) {
        this.userDao.insert(user);
        return user;
    }

    /**
     * 修改数据
     *
     * @param userDTO 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public User update(UserDTO userDTO) {
        User user = new User();
        user = userDao.getByUsername(userDTO.getUsername());
        if(user==null || user.getId() == userDTO.getId()){
            if(user == null)
                user = new User();
            BeanUtils.copyProperties(userDTO,user);
            this.userDao.update(user);
            return this.queryById(user.getId());
        }
        else return user;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.userDao.deleteById(id) > 0;
    }

    @Override
    public Result<User> login(UserLoginDTO userLoginDTO) {
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        User user = userDao.getByUsername(username);
        System.out.println(user);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (user == null) {
            //账号不存在
            return Result.error(null,MessageConstant.ACCOUNT_NOT_FOUND);
//            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        //对前端传过来的密码加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(user.getPassword())) {
            //密码错误
            return Result.error(null,MessageConstant.PASSWORD_ERROR);
//            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (user.getStatus() == StatusConstant.DISABLE) {
            //账号被锁定
            return Result.error(null,MessageConstant.ACCOUNT_LOCKED);
//            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return Result.success(user);
    }

    @Override
    @Transactional
    public User save(UserDTO userDTO) {
        User user = new User();

        //对象属性拷贝
        BeanUtils.copyProperties(userDTO,user);

        //设置账号状态
        user.setStatus(StatusConstant.ENABLE);

        //设置密码，123456 加密后，e10adc3949ba59abbe56e057f20f883e
        user.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        //todo 查询店是否存在

        //todo 查询username和idnumber是否重复
        User byUsername = userDao.getByUsername(user.getUsername());
        if(byUsername==null){
            userDao.insert(user);
            return user;
        }
        else
            return null;
//        System.out.println(user);

    }

    @Override
    public User getById(Long id) {
        User user = userDao.queryById(id);
        return user;
    }

    @Override
    public void startOrStop(Integer status, Long id) {
        User employee = User.builder()
                .status(status)
                .id(id)
                .build();
        userDao.update(employee);
    }

    @Override
    public PageResult pageQuery(UserPageQueryDTO userPageQueryDTO) {
        PageHelper.startPage(userPageQueryDTO.getPage(),userPageQueryDTO.getPageSize());
        com.github.pagehelper.Page<User> page = userDao.pageQuery(userPageQueryDTO);
        int pageSize = (int) page.getTotal();
        List<User> result = page.getResult();
        return new PageResult(pageSize,result);
    }

    @Override
    public Result<List<User>> queryUserByStoreId(Long storeId) {
        List<User> userList = userDao.queryUserByStoreId(storeId);
        return Result.success(userList);
    }

    @Override
    public Result updatePassword(Long id, String oldPassword, String newPassword) {
        User user = userDao.queryById(id);
        //加密
        oldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        if(!Objects.equals(user.getPassword(), oldPassword)){
            return Result.error(MessageConstant.PASSWORD_ERROR);
        }
        user.setPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        userDao.update(user);
        return Result.success(newPassword,"修改成功");
    }


}
